using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace MimeCloud.WPF.Presentation
{
    /// <summary>
    /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
    ///
    /// Step 1a) Using this custom control in a XAML file that exists in the current project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:MimeCloud.WPF.Presentation"
    ///
    ///
    /// Step 1b) Using this custom control in a XAML file that exists in a different project.
    /// Add this XmlNamespace attribute to the root element of the markup file where it is 
    /// to be used:
    ///
    ///     xmlns:MyNamespace="clr-namespace:MimeCloud.WPF.Presentation;assembly=MimeCloud.WPF.Presentation"
    ///
    /// You will also need to add a project reference from the project where the XAML file lives
    /// to this project and Rebuild to avoid compilation errors:
    ///
    ///     Right click on the target project in the Solution Explorer and
    ///     "Add Reference"->"Projects"->[Browse to and select this project]
    ///
    ///
    /// Step 2)
    /// Go ahead and use your control in the XAML file.
    ///
    ///     <MyNamespace:TextWriterDisplay/>
    ///
    /// </summary>
    public class TextWriterDisplay : TextBox
    {
        public TextWriterDisplay()
        {
            Singleton<TextBoxLoggerContext>.AppScoped.TextUpdated += new TextBoxLoggerContext.TextUpdatedDelegate(AppScoped_TextUpdated);

        }
        static void  WTextWriterDisplay()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TextWriterDisplay), new FrameworkPropertyMetadata(typeof(TextWriterDisplay)));
        }
        void AppScoped_TextUpdated(string updated)
        {
            if (!this.Dispatcher.CheckAccess())
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new UpdateTextDelegate(UpdateText), new object[] { updated });
            }
            else
            {
                this.Text += updated + "\r\n";
            }

        }
        private delegate void UpdateTextDelegate(string updateText);
        private void UpdateText(string pString)
        {
            this.Text += pString + Environment.NewLine;
        }

        public class TextBoxLoggerContext : TextWriter
        {
            public delegate void TextUpdatedDelegate(string updated);

            public event TextUpdatedDelegate TextUpdated;
            public void OnTextUpdated(String updatedText)
            {
                if (TextUpdated != null)
                    TextUpdated(updatedText);
            }

            public override Encoding Encoding
            {
                get { return null; }
            }

            public override void WriteLine(string value)
            {
                OnTextUpdated(value);
            }
        }
    }

}


